#include "Scope.h"

namespace FlooP
{
	Scope::Scope () 
	:
		m_output (new Number (0))
	{}

	Scope::Scope (const Scope& copy)
	:
		m_output (new Number(0)),
		m_vars   (copy.m_vars)
	{}

	void Scope::define (const std::string& name)
	{
		m_vars[name] = std::shared_ptr<Object> (new Number (0));
	}

	void Scope::define (const std::string& name, std::shared_ptr<Object> object)
	{
		m_vars[name] = object;
	}

	void Scope::set (const std::string& name, std::shared_ptr<Object> object)
	{
		std::shared_ptr<Object> var = find (name);

		if (var.get () == nullptr) {
			throw Error ("Scope : Variable '%s' has not been defined.", name.c_str ());
		}

		m_vars[name] = object;
	}

	void Scope::clear ()
	{
		m_vars.clear ();
	}

	void Scope::reset ()
	{
		for (auto it = m_vars.begin () ; it != m_vars.end (); it++) {
			(*it).second = std::shared_ptr<Object> (new Number (0));
		}
	}

	std::shared_ptr<Object> Scope::find (const std::string& name)
	{
		auto var = m_vars.find (name);

		if (var == m_vars.end ()) {
			return (std::shared_ptr<Object> ());
		}

		return var->second;
	}

	std::shared_ptr<Object> Scope::output () const
	{
		return m_output;
	}

	std::shared_ptr<Object> Scope::cell (uint32_t num) const
	{
		auto cell = m_cell.find (num);

		if (cell == m_cell.end ()) {
			return (std::shared_ptr<Object> ());
		}

		return cell->second;
	}

	void Scope::set_output (std::shared_ptr<Object> output)
	{
		m_output = output;
	}

	void Scope::set_cell (std::shared_ptr<Object> cell, uint32_t num)
	{
		m_cell[num] = cell;
	}
}